class WorkerPool {
  constructor(workerScript, size = navigator.hardwareConcurrency || 4) {
    this.workerScript = workerScript;
    this.size = size;
    this.workers = [];
    this.queue = [];
    this.activeWorkers = new Map();
    this.initialize();
  }

  initialize() {
    for (let i = 0; i < this.size; i++) {
      const worker = new Worker(this.workerScript);
      worker.onmessage = this.handleMessage.bind(this, worker);
      worker.onerror = this.handleError.bind(this, worker);
      this.workers.push(worker);
    }
  }

  handleMessage(worker, event) {
    const taskId = this.activeWorkers.get(worker);
    if (taskId) {
      const task = this.queue.find(t => t.id === taskId);
      if (task) {
        task.resolve(event.data);
        this.activeWorkers.delete(worker);
        this.processQueue();
      }
    }
  }

  handleError(worker, error) {
    const taskId = this.activeWorkers.get(worker);
    if (taskId) {
      const task = this.queue.find(t => t.id === taskId);
      if (task) {
        task.reject(error);
        this.activeWorkers.delete(worker);
        this.processQueue();
      }
    }
  }

  processQueue() {
    if (this.queue.length === 0) return;

    const availableWorker = this.workers.find(worker => !this.activeWorkers.has(worker));
    if (availableWorker) {
      const task = this.queue.shift();
      this.activeWorkers.set(availableWorker, task.id);
      availableWorker.postMessage(task.data);
    }
  }

  execute(data) {
    return new Promise((resolve, reject) => {
      const taskId = Date.now() + Math.random();
      this.queue.push({ id: taskId, data, resolve, reject });
      this.processQueue();
    });
  }

  terminate() {
    this.workers.forEach(worker => worker.terminate());
    this.workers = [];
    this.queue = [];
    this.activeWorkers.clear();
  }
}

export default WorkerPool; 